package aes.client;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;

import common.*;
import datechooser.beans.*;

public class ExamExecutionTeacherManualUI extends JPanel implements ActionListener, Observer{

	/**
	 * 
	 */
	private static final long serialVersionUID = -6032857349148329181L;
	private ClientUI ui;
	private Client c;

	private JButton btnUpload;
	private JButton btnBack;
	private JButton btnStart;
	private JTextField txtSolveTime;
	private JTextField textCode;
	private DateChooserCombo dateChooserCombo;
	private JSpinner timeSpinner;
	private final JFileChooser fc;
	private File selectedfile = null;

	/**
	 * Constructor
	 * @param c Client object reference
	 * @param ui ClientUI object reference
	 */
	public ExamExecutionTeacherManualUI(Client c,ClientUI ui){
		super();
		this.c = c;
		this.ui = ui;

		JFrame frame = new JFrame();
		frame.setSize(640, 480);
		frame.getContentPane().add(this);

		c.addObserver(this);
		setLayout(new GridBagLayout());


		JPanel panel = new JPanel();
		panel.setBorder(new LineBorder(new Color(0, 0, 0), 2, true));
		panel.setPreferredSize(new Dimension(600,400));

		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.insets = new Insets(5, 0, 5, 0);
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 0;
		add(panel,gbc_panel);
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
		gbl_panel.columnWeights = new double[]{0.0, 1.0};
		panel.setLayout(gbl_panel);

		JLabel lblExamExecTeacherTitle = new JLabel("Manual Exam Execution");
		lblExamExecTeacherTitle.setHorizontalAlignment(SwingConstants.CENTER);
		lblExamExecTeacherTitle.setVerticalAlignment(SwingConstants.TOP);
		lblExamExecTeacherTitle.setBounds(7, 10, 70, 17);
		lblExamExecTeacherTitle.setFont(new Font("Tahoma", Font.BOLD, 14));

		GridBagConstraints gbc_lblExamExecTeacherTitle = new GridBagConstraints();
		gbc_lblExamExecTeacherTitle.anchor = GridBagConstraints.NORTH;
		gbc_lblExamExecTeacherTitle.gridwidth = 2;
		gbc_lblExamExecTeacherTitle.fill = GridBagConstraints.BOTH;
		gbc_lblExamExecTeacherTitle.insets = new Insets(5, 0, 5, 0);
		gbc_lblExamExecTeacherTitle.gridx = 0;
		gbc_lblExamExecTeacherTitle.gridy = 0;
		panel.add(lblExamExecTeacherTitle, gbc_lblExamExecTeacherTitle);

		btnUpload = new JButton("Upload Manual Exam", new ImageIcon(MainUI.class.getResource("/aes/client/images/upload.png")));
		btnUpload.addActionListener(this);

		GridBagConstraints gbc_btnUpload = new GridBagConstraints();
		gbc_btnUpload.anchor = GridBagConstraints.NORTH;
		gbc_btnUpload.gridwidth = 2;
		gbc_btnUpload.insets = new Insets(5, 0, 5, 0);
		gbc_btnUpload.gridx = 0;
		gbc_btnUpload.gridy = 3;
		panel.add(btnUpload, gbc_btnUpload);
		btnUpload.setBounds(353, 7, 57, 23);

		JLabel lblCode = new JLabel("Code:");
		lblCode.setHorizontalAlignment(SwingConstants.LEFT);
		GridBagConstraints gbc_lblCode = new GridBagConstraints();
		gbc_lblCode.anchor = GridBagConstraints.EAST;
		gbc_lblCode.insets = new Insets(0, 0, 5, 5);
		gbc_lblCode.gridx = 0;
		gbc_lblCode.gridy = 4;
		panel.add(lblCode, gbc_lblCode);

		textCode = new JTextField();
		GridBagConstraints gbc_textCode = new GridBagConstraints();
		gbc_textCode.insets = new Insets(0, 0, 5, 10);
		gbc_textCode.fill = GridBagConstraints.HORIZONTAL;
		gbc_textCode.gridx = 1;
		gbc_textCode.gridy = 4;
		panel.add(textCode, gbc_textCode);
		textCode.setColumns(10);
		MaxLengthTextDocument maxLength = new MaxLengthTextDocument();
		maxLength.setMaxChars(5);
		textCode.setDocument(maxLength);

		JLabel lblNewLabel = new JLabel("Solve Time:");
		lblNewLabel.setHorizontalAlignment(SwingConstants.LEFT);
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.EAST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel.gridx = 0;
		gbc_lblNewLabel.gridy = 5;
		lblNewLabel.setBounds(353, 7, 57, 23);
		panel.add(lblNewLabel, gbc_lblNewLabel);

		txtSolveTime = new JTextField();
		GridBagConstraints gbc_txtSolveTime = new GridBagConstraints();
		gbc_txtSolveTime.insets = new Insets(0, 0, 5, 10);
		gbc_txtSolveTime.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtSolveTime.gridx = 1;
		gbc_txtSolveTime.gridy = 5;
		panel.add(txtSolveTime, gbc_txtSolveTime);
		txtSolveTime.setColumns(10);

		JLabel label = new JLabel("Execution Date:");
		GridBagConstraints gbc_label = new GridBagConstraints();
		gbc_label.anchor = GridBagConstraints.EAST;
		gbc_label.insets = new Insets(0, 0, 5, 5);
		gbc_label.gridx = 0;
		gbc_label.gridy = 6;
		panel.add(label, gbc_label);

		dateChooserCombo = new DateChooserCombo();
		GridBagConstraints gbc_dateChooserCombo = new GridBagConstraints();
		gbc_dateChooserCombo.anchor = GridBagConstraints.WEST;
		gbc_dateChooserCombo.insets = new Insets(0, 0, 5, 10);
		gbc_dateChooserCombo.gridx = 1;
		gbc_dateChooserCombo.gridy = 6;
		panel.add(dateChooserCombo, gbc_dateChooserCombo);

		JLabel label_1 = new JLabel("Execution Time:");
		GridBagConstraints gbc_label_1 = new GridBagConstraints();
		gbc_label_1.anchor = GridBagConstraints.EAST;
		gbc_label_1.insets = new Insets(0, 0, 5, 5);
		gbc_label_1.gridx = 0;
		gbc_label_1.gridy = 7;
		panel.add(label_1, gbc_label_1);

		SpinnerModel model = new SpinnerDateModel();
		timeSpinner = new JSpinner(model);
		JComponent editor = new JSpinner.DateEditor(timeSpinner, "HH:mm:ss");
		timeSpinner.setEditor(editor);
		GridBagConstraints gbc_timeSpinner = new GridBagConstraints();
		gbc_timeSpinner.anchor = GridBagConstraints.WEST;
		gbc_timeSpinner.insets = new Insets(0, 0, 5, 5);
		gbc_timeSpinner.gridx = 1;
		gbc_timeSpinner.gridy = 7;
		panel.add(timeSpinner, gbc_timeSpinner);

		btnBack = new JButton("Back", new ImageIcon(ExamsManagerUI.class.getResource("/aes/client/images/back.png")));
		btnBack.addActionListener(this); 
		
		GridBagConstraints gbc_btnBack = new GridBagConstraints();
		gbc_btnBack.anchor = GridBagConstraints.WEST;
		gbc_btnBack.insets = new Insets(5, 10, 0, 5);
		gbc_btnBack.gridx = 0;
		gbc_btnBack.gridy = 10;
		panel.add(btnBack, gbc_btnBack);
		btnBack.setBounds(353, 7, 57, 23);

		btnStart = new JButton("Start", new ImageIcon(ExamsManagerUI.class.getResource("/aes/client/images/execute.png")));
		btnStart.addActionListener(this); 
		GridBagConstraints gbc_btnStart = new GridBagConstraints();
		gbc_btnStart.insets = new Insets(5, 5, 0, 10);
		gbc_btnStart.anchor=GridBagConstraints.EAST;
		gbc_btnStart.gridwidth=2;
		gbc_btnStart.gridx = 0;
		gbc_btnStart.gridy = 10;
		panel.add(btnStart, gbc_btnStart);
		btnStart.setBounds(353, 7, 57, 23);

		fc = new JFileChooser();
		fc.setFileFilter(new FileFilter() {
			public boolean accept(File f) {
				return f.getName().toLowerCase().endsWith(".doc")
						|| f.isDirectory() || f.getName().toLowerCase().endsWith(".docx");
			}

			public String getDescription() {
				return "Word Files";
			}
		});
	}

	/**
	 * Message received event handler
	 */
	@SuppressWarnings("static-access")
	@Override
	public void update(Observable arg0, Object arg1) {
		if (arg1 instanceof CommandMessage) {
			CommandMessage ms=(CommandMessage)arg1;
			if (ms.getCommand().equals(CommandMessage.ACKNOWLEDGE_MESSAGE) && ((String)ms.getParams()[0]).equals(CommandMessage.ADD_EXAM_EXECUTION)) {
				int res = new Integer(ms.getParams()[1].toString());
				if (res == -1) {
					// Code already exists.
					ui.ShowMessageBox("ERROR", "Execution code already exists please try another one", JOptionPane.ERROR_MESSAGE);
				}
				else if (res == 0) {
					// Can't add exam execution.
					ui.ShowMessageBox("ERROR", "Can't execute exam", JOptionPane.ERROR_MESSAGE);
				}
				else {
					// Added.
					ui.ShowMessageBox("Information", "Exam execution started. Execution code is: " + textCode.getText(), JOptionPane.INFORMATION_MESSAGE);
					ui.SetContent(ui.TEACHER_EXAM_EXECUTION_SCREEN);
				}
			}
		}
	}

	/**
	 * Buttons click event handler
	 */
	@SuppressWarnings({ "static-access", "deprecation" })
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(btnBack)) {
			ui.SetContent(ui.TEACHER_EXAM_EXECUTION_SCREEN);
		}
		else if (e.getSource().equals(btnUpload)) {
			// Choose file.
			int returnVal = fc.showOpenDialog(ui);

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				selectedfile = fc.getSelectedFile();
			} 
		}
		else if (e.getSource().equals(btnStart)) {
			if (checkForm())
			{
				// Start execution.
				ManualExamExecution me = new ManualExamExecution();
				me.setCode(textCode.getText().trim());
				me.setDefinedTime(Integer.parseInt(txtSolveTime.getText()));
				me.setExecTeacherID(ui.getUser().getId());
				Date time = dateChooserCombo.getSelectedDate().getTime();
				Date val = (Date)timeSpinner.getModel().getValue();
				time.setHours(val.getHours());
				time.setMinutes(val.getMinutes());
				time.setSeconds(val.getSeconds());
				me.setExecutionDate(time);

				// Read file.
				byte[] data;
				try {
					FileInputStream fin = new FileInputStream(selectedfile);
					me.setFileName(selectedfile.getName());
					data = new byte[(int)selectedfile.length()];

					fin.read(data);
					fin.close();
				}
				catch(FileNotFoundException ex1)
				{
					ui.ShowMessageBox("ERROR", "Exam file not found", JOptionPane.ERROR_MESSAGE);
					return;
				}
				catch(IOException ioe)
				{
					ui.ShowMessageBox("ERROR", "Can't read exam file", JOptionPane.ERROR_MESSAGE);
					return;
				}

				me.setFileData(data);

				CommandMessage msg = new CommandMessage(CommandMessage.ADD_EXAM_EXECUTION, new Object[] {me});
				try {
					c.sendToServer(msg);
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
	}

	@SuppressWarnings("static-access")
	private boolean checkForm() {
		int solveTime;
		if (textCode.getText().trim().length() != 4) {
			ui.ShowMessageBox("ERROR", "Please fill execution code 4 characters long", JOptionPane.ERROR_MESSAGE);
			return false; 
		}
		try {  
			solveTime=Integer.parseInt( txtSolveTime.getText() );  
			if (solveTime < 1)
			{
				ui.ShowMessageBox("ERROR", "Solve time must be positive", JOptionPane.ERROR_MESSAGE);
				return false; 
			}
		}  
		catch( Exception ex) {  
			ui.ShowMessageBox("ERROR", "Solve time must be numeric", JOptionPane.ERROR_MESSAGE);
			return false;  
		}
		return true;
	}
}
